import React from 'react'
import { Button, Form, Tag } from 'antd'
import Chooser from 'components/chooser'
import ListSelector from 'components/list-selector'
import chooserData from 'share/chooserData'
const FormItem = Form.Item;

export default {
  key: 'chooser',
  name: 'Chooser 选择器',
  author: '张然',
  description: '用于在大量远程数据中选择想要的数据的情况，将业务接口的调用、数据结构封装在内，支持所有数据的分页、搜索（非关键字搜索）、单选、多选操作。内部是由antd的::Select::、::Table::与本项目的::SearchArea::组合而成的，可集成在antd的::Form::中。',
  isExampleFull: false,
  api: [
    {
      title: 'API',
      data: [{
        param: 'type', description: '内部::ListSelector::的::type::，详情见下方::ListSelector::。', type: 'string', defaultValue: '-'
      },{
        param: 'selectorItem', description: '内部::ListSelector::的::selectorItem::，详情见下方::ListSelector::。', type: 'object', defaultValue: '-'
      },{
        param: 'placeholder', description: '组件没有选择值时显示的文字。', type: 'string', defaultValue: '请选择'
      },{
        param: 'disabled', description: '组件是否禁用。', type: 'boolean', defaultValue: 'false'
      },{
        param: 'labelKey', description: '已选中的值在组件内显示的字段名。', type: 'string', defaultValue: '-'
      },{
        param: 'valueKey', description: '已选中的值在组件内用作key值的字段名。', type: 'string', defaultValue: '-'
      },{
        param: 'onChange', description: '组件的值发生改变时的回调。', type: 'function(array)', defaultValue: '-'
      },{
        param: 'single', description: '是否单选。', type: 'boolean', defaultValue: 'false'
      },{
        param: 'value', description: '组件的值，该值内的每一个对象必须包含此组件设置的::labelKey::字段与::valueKey::字段。', type: 'array', defaultValue: '-'
      },{
        param: 'showNumber', description: '是否只显示已选择了几条。', type: 'boolean', defaultValue: 'false'
      },{
        param: 'newline', description: '组件内部的值是否会换行。', type: 'boolean', defaultValue: 'false'
      },{
        param: 'onlyNeed', description: '如果设置了该值，组件通过::onChange::返回的值只会包含对象的以此值为key的字段，而不会返回整个对象。', type: 'boolean', defaultValue: 'false'
      },{
        param: 'maxNum', description: '最大选择数量。', type: 'number', defaultValue: '-'
      },{
        param: 'method', description: '请求::type::对应的数据结构或::selectorItem::中的::url::的方法。', type: 'string', defaultValue: 'get'
      },{
        param: 'showClear', description: '是否展示清空按钮。', type: 'boolean', defaultValue: 'true'
      },{
        param: 'showDetail', description: '是否在::ListSelector::内显示上方已选择值的Tag。', type: 'boolean', defaultValue: 'true'
      },{
        param: 'showArrow', description: '是否在::ListSelector::内显示上方已选择值的Tag中间显示箭头。', type: 'boolean', defaultValue: 'true'
      },{
        param: 'listExtraParams', description: '内部::ListSelector::组件需要的::extraParams::，详见下方::ListSelector::', type: 'object', defaultValue: '-'
      }],
      description: ''
    },
    {
      title: 'ListSelector',
      data: [{
        param: 'visible', description: '控制组件是否显示。', type: 'boolean', defaultValue: 'false'
      },{
        param: 'type', description: '组件的数据结构方法，本项目中存储在::share/chooserData.js::中，只能为已定义的数据结构中的一个的key值，数据结构配置见下方::selectorItem::。', type: 'string', defaultValue: '-'
      },{
        param: 'single', description: '是否单选。', type: 'boolean', defaultValue: 'false'
      },{
        param: 'maxNum', description: '最多选择多少条数据，如果不设置则没有限制。', type: 'number', defaultValue: '-'
      },{
        param: 'selectorItem', description: '如果::type::定义的数据结构并不能满足特定需求，可以通过改造数据结构并通过此值传入形成特定的选择器，具体配置见下方::selectorItem::。', type: 'object', defaultValue: '-'
      },{
        param: 'method', description: '::type::指定的数据结构或::selectorItem::数据内请求对应::url::时的方法。', type: 'string', defaultValue: 'get'
      },{
        param: 'extraParams', description: '::type::指定的数据结构或::selectorItem::数据内请求对应::url::时需要的额外参数。', type: 'object', defaultValue: '-'
      },{
        param: 'labelKey', description: '请求::type::指定的数据结构或::selectorItem::内url后的结果数组或::selectedData::数组中需要在::Tag::内当作::label::显示的对象内对应字段名。', type: 'string', defaultValue: '-'
      },{
        param: 'selectedData', description: '已选择的值列表，每个对象必须包含::type::指定的数据结构或::selectorItem::内指定的::key:字段。', type: 'array', defaultValue: '-'
      },{
        param: 'selectAll', description: '是否显示选择全部按钮。', type: 'boolean', defaultValue: 'false'
      },{
        param: 'onSelectAll', description: '点击选择全部按钮后触发的事件。', type: 'function', defaultValue: '() => {}'
      },{
        param: 'selectAllLoading', description: '选择全部按钮的::loading::状态。', type: 'boolean', defaultValue: 'false'
      },{
        param: 'showDetail', description: '是否在内部表格上方显示已选择值的::Tag::。', type: 'boolean', defaultValue: 'true'
      },{
        param: 'showArrow', description: '是否在内部表格上方已选择值的::Tag::中间加上箭头。', type: 'boolean', defaultValue: 'false'
      },{
        param: 'onOk', description: '点击确认按钮的回调。', type: 'function(value{result, type})', defaultValue: '() => {}'
      },{
        param: 'onCancel', description: '点击取消或右上角关闭按钮的回调。', type: 'function', defaultValue: '() => {}'
      },{
        param: 'afterClose', description: '完全关闭组件后的回调。', type: 'function', defaultValue: '() => {}'
      },{
        param: 'confirmLoading', description: '确认按钮的::loading::状态。', type: 'boolean', defaultValue: 'false'
      }],
      description: '每一个::Chooser::内部都有有一个::ListSelector::，内部的::ListSelector::依附于外部::Chooser::的参数，但是也可以单独拿出来使用。'
    },
    {
      title: 'selectorItem',
      data: [{
        param: 'title', description: '标题。', type: 'string', defaultValue: '-'
      },{
        param: 'url', description: '接口请求地址，参数会自带::page::、::size::的分页属性（::size::默认为10）、::SearchArea::的结果对象以及::extraParams::。', type: 'string', defaultValue: '-'
      },{
        param: 'searchForm', description: '内部::SearchArea::需要的::searchForm::。详见::SearchArea::', type: 'array', defaultValue: '-'
      },{
        param: 'columns', description: '内部::Table::需要的::columns::，此::Table::自带分页，::dataSource::为请求::url::后的结果数组。', type: 'array', defaultValue: '-'
      },{
        param: 'key', description: '内部数据的唯一标识的字段名，用于::selectedData::区分。', type: 'string', defaultValue: '-'
      }],
      description: '每一个::ListSelector::都是由一个::selectorItem::渲染而来，本项目中此类数据有一个专门的文件::share/chooserData.js::。每一个对象的::key::值可用于::ListSelector::的::type::用于简化调用。'
    }
  ],
  example: [
    {
      title: '基础用法',
      description: '点击组件后弹出选择框，选择完成后值回填至组件。通过设置::type::为项目内在::chooserData::中封装好的数据即可快速形成一个远程数据选择器。设置::showNumber::属性可以只显示选择的数量。',
      state: {},
      getMethod: context => {
        return {
          handleChange: data => {
            console.log(data)
          }
        }
      },
      getContent: context => {
        const {  } = context.state;
        return (
          <div style={{ width: '100%' }}>
            <Chooser type='user'
                     valueKey="userOID"
                     labelKey="fullName"
                     onChange={context.handleChange}/>
            <br/>
            <Chooser type='user'
                     valueKey="userOID"
                     labelKey="fullName"
                     onChange={context.handleChange}
                     showNumber/>
          </div>
        )
      }
    },
    {
      title: '禁用、多行与单选',
      description: '通过设置::disabled::可禁用组件，通过设置::newline::可设置多行，设置::single::即可转换为单选。',
      state: {
        value: [{
          userOID: 'firstID', fullName: 'There is a long name!'
        },{
          userOID: 'secondID', fullName: 'Short name'
        },{
          userOID: 'thirdID', fullName: 'Third user'
        },{
          userOID: 'forthID', fullName: 'Another user'
        }]
      },
      getMethod: context => {
        return {
          handleChange: value => {
            context.setState({ value })
          }
        }
      },
      getContent: context => {
        const { value } = context.state;
        return (
          <div style={{ width: '100%' }}>
            <Chooser type='user'
                     valueKey="userOID"
                     labelKey="fullName"
                     disabled
                     placeholder="禁用的组件"/>
            <br/>
            <Chooser type='user'
                     valueKey="userOID"
                     labelKey="fullName"
                     newline
                     onChange={context.handleChange}
                     value={value}/>
            <br/>
            <Chooser type='user'
                     valueKey="userOID"
                     labelKey="fullName"
                     placeholder="单选"
                     single/>
          </div>
        )
      }
    },
    {
      title: '数据处理',
      description: '通过设置不同的::labelKey::可让同::type::的组件显示不同的字段显示值，通过设置不同的::valueKey::可让同::type::的组件以不同的::key::进行处理（常用于初始值的设置）。',
      state: {},
      getMethod: context => {
        return {
          handleChange: data => {
            console.log(data)
          }
        }
      },
      getContent: context => {
        const {  } = context.state;
        return (
          <div style={{ width: '100%' }}>
            <Chooser type='user'
                     valueKey="userOID"
                     labelKey="fullName"
                     onChange={context.handleChange}/>
            <p>labelKey为fullName时显示姓名</p>
            <Chooser type='user'
                     valueKey="userOID"
                     labelKey="employeeID"
                     onChange={context.handleChange}/>
            <p>labelKey为employeeID时显示工号</p>
          </div>
        )
      }
    },
    {
      title: 'selectorItem',
      description: '如果设置的::type::的默认数据结构不能满足一些特殊需求，则可以通过传入::selectorItem::进行默认::type::结构的二次开发版。',
      state: {},
      getMethod: context => {
        return {
          handleChange: data => {
            console.log(data)
          }
        }
      },
      getContent: context => {
        const {  } = context.state;
        let selectorItem =  JSON.parse(JSON.stringify(chooserData['user']));
        selectorItem.columns = [
          {
            title:  '工号',
            dataIndex: 'employeeID'
          },
          {
            title: '姓名',
            dataIndex: 'fullName'
          }
        ];
        selectorItem.searchForm[0].defaultValue = '张';
        return (
          <div style={{ width: '100%' }}>
            <Chooser type='user'
                     valueKey="userOID"
                     labelKey="fullName"
                     onChange={context.handleChange}/>
            <p>默认的人员选择器</p>
            <Chooser type='user'
                     valueKey="userOID"
                     labelKey="employeeID"
                     onChange={context.handleChange}
                     selectorItem={selectorItem}/>
            <p>只显示工号和姓名且头部SearchArea有默认值的同type选择器</p>
          </div>
        )
      }
    },
    {
      title: '最大选择数量',
      description: '如果设置的::maxNum::可设置最大选择数量。',
      state: {},
      getMethod: context => {
        return {
          handleChange: data => {
            console.log(data)
          }
        }
      },
      getContent: context => {
        const {  } = context.state;
        return (
          <div style={{ width: '100%' }}>
            <Chooser type='user'
                     valueKey="userOID"
                     labelKey="fullName"
                     maxNum={3}
                     placeholder="最多只能选择3个"
                     onChange={context.handleChange}/>
          </div>
        )
      }
    },
    {
      title: '兼容antd的表单',
      description: '本组件可用于antd的::Form::组件中，使用::getFieldDecorator::包裹即可与antd表单一同使用。',
      state: {},
      getMethod: context => {
        return {
          handleSubmit: e => {
            e.preventDefault();
            context.props.form.validateFieldsAndScroll((err, values) => {
              if (!err) {
                console.log('Received values of form: ', values);
              }
            });
          }
        }
      },
      getContent: context => {
        const {  } = context.state;
        const { getFieldDecorator } = context.props.form;
        return (
          <Form onSubmit={context.handleSubmit}>
            <FormItem label='人员' style={{ marginBottom: 12 }}>
              {getFieldDecorator('user', {
                rules: [{
                  required: true,
                  message: '请输入'
                }]
              })(
                <Chooser type='user'
                         valueKey="userOID"
                         labelKey="fullName"/>
              )}
            </FormItem>
            <FormItem>
              <Button type="primary" htmlType="submit">提交</Button>
            </FormItem>
          </Form>
        )
      }
    },
    {
      title: 'ListSelector',
      description: '::Chooser::组件内部的::ListSelector::可单独使用，不依托::Chooser::。',
      state: {
        show: false,
        value: []
      },
      getMethod: context => {
        return {
          handleChange: data => {
            context.setState({ show: false, value: data.result });
            console.log(data)
          }
        }
      },
      getContent: context => {
        const { show, value } = context.state;
        return (
          <div style={{ width: '100%' }}>
            <Button onClick={() => context.setState({ show: true })} type="primary">选择人员</Button>
            <div style={{ marginTop: 10 }}>
              已选择: {value.map(item => <Tag color="magenta" key={item.userOID}>{item.fullName}</Tag>)}
            </div>
            <ListSelector type='user'
                          valueKey="userOID"
                          labelKey="fullName"
                          onOk={context.handleChange}
                          selectedData={value}
                          visible={show}
                          onCancel={() => context.setState({ show: false })}/>
          </div>
        )
      }
    },
    {
      title: '全选与confirmLoading',
      description: '::ListSelector::可以通过设置::selectAll::增加全选按钮，当然实际是不可能拿到所有数据的，这里只能给一个方法给外部，在外部进行选择全部的操作。同时可以设置全选的loading以及ok的loading。',
      state: {
        allLoading: false,
        show: false,
        confirmLoading: false,
        value: []
      },
      getMethod: context => {
        return {
          handleChange: data => {
            context.setState({ confirmLoading: true } ,() => {
              setTimeout(() => {
                context.setState({ show: false, value: data.result, confirmLoading: false });
                console.log(data)
              }, 2000);
            });
          },
          handleSelectAll: () => {
            context.setState({ allLoading: true } ,() => {
              setTimeout(() => {
                context.setState({ show: false, allLoading: false });
                console.log('选择了全部。')
              }, 2000);
            });
          }
        }
      },
      getContent: context => {
        const { allLoading, confirmLoading, value, show } = context.state;
        return (
          <div style={{ width: '100%' }}>
            <Button onClick={() => context.setState({ show: true })} type="primary">选择人员</Button>
            <ListSelector type='user'
                          valueKey="userOID"
                          labelKey="fullName"
                          onOk={context.handleChange}
                          selectedData={value}
                          visible={show}
                          onCancel={() => context.setState({ show: false })}
                          selectAll
                          selectAllLoading={allLoading}
                          confirmLoading={confirmLoading}
                          onSelectAll={context.handleSelectAll}/>
          </div>
        )
      }
    }
  ]
}
